<?php
include_once $_SERVER['DOCUMENT_ROOT'].'/phorm/database/core/Database.php';
include_once $_SERVER['DOCUMENT_ROOT'].'/phorm/database/core/IDatabaseRecord.php';
include_once $_SERVER['DOCUMENT_ROOT'].'/phorm/database/mysql/MySQLCRUD.php';
include_once $_SERVER['DOCUMENT_ROOT'].'/phorm/utils/FileUtils.php';

require 'DatabaseRecord.php';
class MySQLRecord extends DatabaseRecord implements IDatabaseRecord
{
	
	public function initWithColumns() { /* pass */ }
	
	public function create()
	{
		return MySQLCRUD::buildTable($this);
	}

	public function emptyThis()
	{
		return MySQLCRUD::emptyTable($this);
	}

	public function drop()
	{
		return MySQLCRUD::dropTable($this);
	}
	
	public function initWithPrimaryKey($id)
	{
		$class = get_class($this);
		$q = new MySQLQuery($class);
		$q->filter($class.'->'.$this->primary_key->column.' = '.$id);
		
		$q->resultsAsArray = true;
		
		foreach($q->one() as $key=>$value)
		{
			$pos             = strpos($key, '_');
			$property        = substr($key, ($pos+1));
			
			$this->columns[$property]->value = $value;
		}
		
		$this->isNew = false;
		
		unset($q);
		unset($class);
	}
	
	public function save()
	{
		$query                   = MySQLCRUD::buildSaveQuery($this);
		$shouldCommitTransaction = true;	
		$shouldSetPrimaryKey     = false;
		
		// since we could have a situation where we
		// have an IAutoUpdateColumn use the database,
		// such as Featured.php we make a transaction connection.
		
		$dbh     =& Database::transactionConnection();

		// this needs to be rethought.. it's duplicating logic...
		if ($this->isNew && $this->primary_key && empty($this->primary_key->value))
			$shouldSetPrimaryKey = true;
			
		/*if ($this->isNew && $this->primary_key->auto_increment == true && empty($this->primary_key->value))
			$shouldSetPrimaryKey = true;
		else if ($this->isNew && $this->primary_key->auto_increment == false && empty($this->primary_key->value))
			$shouldSetPrimaryKey = true;*/
		$stmt  = $dbh->prepare($query);
		/*  make sure we have a prepared statement.
			in php 5.1.6 at least, there must be a bug as
			$stmt  = $dbh->prepare($query); where $dbh
			is a persistentConnection or a transactionConnection
			will be empty. So check to see if it's empty,
			and if it is default to Database::connection().
			Be aware, there is no logic in place to handle why
			we were using the transactionConnection here in the 
			first place (Featured.php), so something else will
			go wrong if this is a Featured column.
		*/
		if (empty($stmt))
		{
			Database::commit();
			$dbh =& Database::connection();
			$shouldCommitTransaction = false;
			$stmt  = $dbh->prepare($query);
		}
		
		foreach ($this->columns as $key=>$value)
		{
			if (!($value instanceof IIgnorableColumn))
			{
				if ($value instanceof PrimaryKey)
				{
					if ($this->columns[$key]->auto_increment == false && $this->isNew && $value->field_type != 'uuid')
					{
						$stmt->bindParam(':'.$key, @$this->columns[$key]->value);
					}
				}
				else
				{
					// $value->update could access the database, that is why
					// we are using a Transaction connection here.
					if ($value instanceof IAutoUpdateColumn) 
					{
						$value->update();
					}

					if (!$this->isNew)
					{
						if($value->isDirty && !($value instanceof IInsertOnlyColumn))
						{
							//echo 'Is Dirty: ',$value->isDirty,':',$key,'=',$value->value,'<br>';
							$stmt->bindParam(':'.$key, $value->value);
						}
					}
					else
					{
						// Insert only will ONLY happen on save, never on update this way.
						if ($value instanceof IInsertOnlyColumn)
							$value->insert();
							
						//echo 'Binding: ', $key, ' to: ', $value->value, '<br>';
						//$in = $value->value;
						//$v = $value->value;
						$stmt->bindParam(':'.$key, $value->value);
					}
				}
			}
		}
		
		$stmt->execute();
		// if this was an Insert, then he record is no longer new
		if ($this->isNew) $this->isNew = false;
		
		if ($shouldSetPrimaryKey)
		{
			if($this->primary_key->auto_increment == false && $this->primary_key->field_type == 'uuid')
			{
				if($shouldCommitTransaction)
					Database::commit();
				else
					Database::finish();
					
				$class             = get_class($this);
				$q                 = new MySQLQuery($class);
				$q->resultsAsArray = true;
				
				foreach ($this->columns as $key=>$value)
				{
					if($value->value)
						$q->filter($class.'->'.$key.'= "'.$value->value.'"');
				}
				
				$row = $q->one();
				$this->primary_key->value = $row[strtolower($class).'_'.$this->primary_key->column];
			}
			else
			{
				$this->primary_key->value = $dbh->lastInsertId();
				
				if($shouldCommitTransaction)
					Database::commit();
				else
					Database::finish();
			}
		}
		else
		{
			if($shouldCommitTransaction)
				Database::commit();
			else
				Database::finish();
		}
	}
	
	public function delete($id = null)
	{
		$files = array();
		
		try
		{
			if ($id == null && $this->primary_key->value)
				$id = $this->primary_key->value;
			elseif ($id == null && $this->primary_key->value == null)
				throw new Exception('Warning: MySQLRecord->delete() attempted but no argument \'$id\' provided and no primary_key is set');
		}
		catch(Exception $e)
		{
			echo $e->getMessage();
		}

		foreach ($this->columns as $key=>$column)
		{	
			if ($column instanceof File)
				$files[$key] = $column;
		}

		if (count($files) && $this->isNew && $id)
		{
			$this->hydrateWithPrimaryKey($id);
			//$this->initWithId($id);
			foreach ($files as $key=>$value)
			{
				if($value->value)
				{
					$path = $value->path;
					
					if($value->shouldAppendColumnToPath)
						$path .= '/'.$value->column;
				
					FileUtils::delete($path.'/'.$value->value);
				}
			}
		}
		else if (count($files) && $this->isNew == false)
		{
			foreach ($files as $key=>$value)
			{
				if($value->value)
				{
					$path = $value->path;
					
					if($value->shouldAppendColumnToPath)
						$path .= '/'.$value->column;
				
					FileUtils::delete($path.'/'.$value->value);
				}
			}
		}
	
		$query = MySQLCRUD::buildDeleteQuery($this, $id);
		$dbh   =& Database::connection();
		$dbh->query($query);
		Database::finish();
	}
}
?>
